package com.house.rent.manager;

import android.content.Context;
import android.graphics.Bitmap;
import android.net.Uri;
import android.text.TextUtils;

import androidx.annotation.Nullable;

import com.facebook.cache.common.CacheKey;
import com.facebook.cache.disk.DiskCacheConfig;
import com.facebook.common.executors.CallerThreadExecutor;
import com.facebook.common.internal.Supplier;
import com.facebook.common.logging.FLog;
import com.facebook.common.references.CloseableReference;
import com.facebook.datasource.DataSource;
import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.imagepipeline.cache.CountingMemoryCache;
import com.facebook.imagepipeline.cache.ImageCacheStatsTracker;
import com.facebook.imagepipeline.core.ImagePipeline;
import com.facebook.imagepipeline.core.ImagePipelineConfig;
import com.facebook.imagepipeline.datasource.BaseBitmapDataSubscriber;
import com.facebook.imagepipeline.image.CloseableImage;
import com.facebook.imagepipeline.request.ImageRequest;
import com.facebook.imagepipeline.request.ImageRequestBuilder;

import java.io.File;

/**
 * @author : neo.duan
 * @date : 	 2016/8/13
 * @desc : 图片管理器:用于管理加载图片，目前用的是Facebook出品Fresco
 * see ： see:http://fresco-cn.org/docs/index.html
 */
public class ImageManager {
    private static final String PHOTO_FRESCO = "frescocache";
    private final String TAG = "ImageManager";

    private ImageManager() {
    }

    public static final ImageManager getInstance() {
        return ImageManagerHolder.instance;
    }

    /**
     * 初始化配置缓存策略
     */
    public void init(final Context context) {
//        以下为配置项，目前使用默认 see:http://fresco-cn.org/docs/index.html

//        ImagePipelineConfig config = ImagePipelineConfig.newBuilder(context)
//                .setBitmapMemoryCacheParamsSupplier(bitmapCacheParamsSupplier)
//                .setCacheKeyFactory(cacheKeyFactory)
//                .setDownsampleEnabled(true)
//                .setWebpSupportEnabled(true)
//                .setEncodedMemoryCacheParamsSupplier(encodedCacheParamsSupplier)
//                .setExecutorSupplier(executorSupplier)
//                .setImageCacheStatsTracker(imageCacheStatsTracker)
//                .setMainDiskCacheConfig(mainDiskCacheConfig)
//                .setMemoryTrimmableRegistry(memoryTrimmableRegistry)
//                .setNetworkFetchProducer(networkFetchProducer)
//                .setPoolFactory(poolFactory)
//                .setProgressiveJpegConfig(progressiveJpegConfig)
//                .setRequestListeners(requestListeners)
//                .setSmallImageDiskCacheConfig(smallImageDiskCacheConfig)
//                .build();
//        Fresco.initialize(context, config);

        DiskCacheConfig diskCacheConfig = DiskCacheConfig.newBuilder(context)
                .setMaxCacheSize(1000 * 1024 * 1024)//最大缓存
                .setBaseDirectoryName(PHOTO_FRESCO)//子目录
                .setBaseDirectoryPathSupplier(new Supplier<File>() {
                    @Override
                    public File get() {
                        return context.getCacheDir();//还是推荐缓存到应用本身的缓存文件夹,这样卸载时能自动清除,其他清理软件也能扫描出来
                    }
                })
                .build();
        MyImageCacheStatsTracker imageCacheStatsTracker = new MyImageCacheStatsTracker();//缓存的监听接口,其方法空实现即可
        ImagePipelineConfig config = ImagePipelineConfig.newBuilder(context)
                .setMainDiskCacheConfig(diskCacheConfig)
                .setImageCacheStatsTracker(imageCacheStatsTracker)
                .setDownsampleEnabled(true)
                //Downsampling，要不要向下采样,它处理图片的速度比常规的裁剪scaling更快，
                // 并且同时支持PNG，JPG以及WEP格式的图片，非常强大,与ResizeOptions配合使用
                .setBitmapsConfig(Bitmap.Config.RGB_565)
                //如果不是重量级图片应用,就用这个省点内存吧.默认是RGB_888
                .build();

        Fresco.initialize(context, config);
        FLog.setMinimumLoggingLevel(FLog.VERBOSE);
    }

    /**
     * 检查图片是否已缓存
     *
     * @param url
     * @return
     */
    public boolean isCache(String url) {
        return isMemoryCache(url) || isInDiskCache(url);
    }

    /**
     * 检查图片是否已缓存在内存中，非disk
     *
     * @param url 图片url
     * @return
     */
    public boolean isMemoryCache(String url) {
        if (TextUtils.isEmpty(url)) {
            return false;
        }
        ImagePipeline pipeline = Fresco.getImagePipeline();
        return pipeline.isInBitmapMemoryCache(Uri.parse(url));
    }

    /**
     * 检查图片是否已缓存在disk中
     *
     * @param url 图片url
     * @return
     */
    public boolean isInDiskCache(String url) {
        if (TextUtils.isEmpty(url)) {
            return false;
        }
        ImagePipeline pipeline = Fresco.getImagePipeline();
        return pipeline.isInDiskCacheSync(Uri.parse(url));
    }

    /**
     * 清除缓存中某个图片
     *
     * @param url 图片url
     */
    public void clearFromCache(String url) {
        ImagePipeline pipeline = Fresco.getImagePipeline();
        pipeline.evictFromCache(Uri.parse(url));
    }

    /**
     * 清除全部缓存
     */
    public void clearCache() {
        ImagePipeline imagePipeline = Fresco.getImagePipeline();
        imagePipeline.clearMemoryCaches();
        imagePipeline.clearDiskCaches();
        //或者 imagePipeline.clearCaches();
    }

    /**
     * 清除全部disk上图片缓存：一般用于用户手动清除缓存
     */
    public void clearDiskCaches() {
        ImagePipeline imagePipeline = Fresco.getImagePipeline();
        imagePipeline.clearDiskCaches();
    }

    /**
     * 清除全部disk上图片缓存：一般用于应用低内存时
     */
    public void clearMemoryCaches() {
        ImagePipeline imagePipeline = Fresco.getImagePipeline();
        imagePipeline.clearMemoryCaches();
    }

    /**
     * 获取缓存大小
     *
     * @return
     */
    public long getCacheSize() {
        return Fresco.getImagePipelineFactory().getMainFileCache().getSize();
    }

    /**
     * 下载图片
     */
    public void downLoad(String url, final DownLoadImageListener listener) {
        Uri uri = Uri.parse(url);
        ImageRequest imageRequest = ImageRequestBuilder.newBuilderWithSource(uri).setProgressiveRenderingEnabled(true).build();
        ImagePipeline imagePipeline = Fresco.getImagePipeline();
        DataSource<CloseableReference<CloseableImage>> dataSource = imagePipeline.fetchDecodedImage(imageRequest, this);
        dataSource.subscribe(new BaseBitmapDataSubscriber() {
            @Override
            public void onNewResultImpl(@Nullable Bitmap bitmap) {
                //bitmap即为下载所得图片
                if (listener != null) {
                    listener.onSuccess(bitmap);
                }
            }

            @Override
            public void onFailureImpl(DataSource dataSource) {
                if (listener != null) {
                    Throwable throwable = new Throwable();
                    if (dataSource != null) {
                        throwable = dataSource.getFailureCause();
                    }
                    listener.onFailure(throwable);
                }
            }
        }, CallerThreadExecutor.getInstance());
    }

    public interface DownLoadImageListener {
        void onSuccess(Bitmap bitmap);

        void onFailure(Throwable throwable);
    }

    private static class ImageManagerHolder {
        private static final ImageManager instance = new ImageManager();
    }

    public static class MyImageCacheStatsTracker implements ImageCacheStatsTracker {
        @Override
        public void onBitmapCachePut() {

        }

        @Override
        public void onBitmapCacheHit(CacheKey cacheKey) {

        }


        @Override
        public void onBitmapCacheMiss() {

        }

        @Override
        public void onMemoryCachePut() {

        }

        @Override
        public void onMemoryCacheHit(CacheKey cacheKey) {

        }


        @Override
        public void onMemoryCacheMiss() {

        }

        @Override
        public void onStagingAreaHit(CacheKey cacheKey) {

        }

        @Override
        public void onStagingAreaMiss() {

        }

        @Override
        public void onDiskCacheHit(CacheKey cacheKey) {

        }

        @Override
        public void onDiskCacheMiss() {
            //Logger.e("ImageCacheStatsTracker---onDiskCacheMiss");
        }

        @Override
        public void onDiskCacheGetFail() {
            //Logger.e("ImageCacheStatsTracker---onDiskCacheGetFail");
        }

        @Override
        public void registerBitmapMemoryCache(CountingMemoryCache<?, ?> countingMemoryCache) {

        }

        @Override
        public void registerEncodedMemoryCache(CountingMemoryCache<?, ?> countingMemoryCache) {

        }
    }

}
